;; This file is part of Scheme-GNUnet.
;; Copyright © 2001-2011, 2022 GNUnet e.V.
;;
;; Scheme-GNUnet is free software: you can redistribute it and/or modify it
;; under the terms of the GNU Affero General Public License as published
;; by the Free Software Foundation, either version 3 of the License,
;; or (at your option) any later version.
;;
;; Scheme-GNUnet is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; Affero General Public License for more details.
;;
;; You should have received a copy of the GNU Affero General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;
;; SPDX-License-Identifier: AGPL-3.0-or-later

;; Author (C code): Bartlomiej Polot
;; Author (Scheme port): Maxime Devos

(define-library (gnu gnunet cadet struct)
  (export /:msg:cadet:port /:msg:cadet:local:channel:create
	  /:msg:cadet:local:channel:destroy /:msg:cadet:local:data
	  /:msg:cadet:local:acknowledgement
	  %minimum-local-channel-id)
  (import (only (rnrs base) define begin quote)
	  (only (gnu gnunet util struct)
		/:message-header)
	  (only (gnu gnunet netstruct syntactic)
		define-type structure/packed)
	  (only (gnu gnunet netstruct procedural)
		u32/big)
	  (only (gnu gnunet crypto struct)
		/peer-identity)
	  (only (gnu gnunet hashcode struct)
		/hashcode:512))
  (begin
    ;; Minimum value for channel IDS of local clients.
    (define %minimum-local-channel-id #x80000000)

    ;; Number uniquely identifying a channel of a client.
    ;; Local channel numbers given by the service (incoming) are
    ;; smaller than GNUNET_CADET_LOCAL_CHANNEL_ID_CLI.
    ;; Local channel numbers given by the client (created) are
    ;; larger than GNUNET_CADET_LOCAL_CHANNEL_ID_CLI.
    ;; TODO: are these strict inequalities?
    ;; TODO: make cadet.h more explicit.
    (define-type /client-channel-number u32/big)

    (define-type /:msg:cadet:port
      (structure/packed
       (synopsis
	"Message from a client to the service, to create or destroy a port")
       (properties '((message-symbol msg:cadet:local:port:open
				     msg:cadet:local:port:close)
		     (c-type . GNUNET_CADET_PortMessage)))
       (field (header /:message-header))
       (field (port /hashcode:512)
	      (synopsis "Port to open/close."))))

    (define-type /:msg:cadet:local:channel:create
      (structure/packed
       ;; TODO: from client to service?
       (synopsis "Message for a client to create channels")
       (properties '((message-symbol . msg:cadet:local:channel:create)
		     (c-type . GNUNET_CADET_LocalChannelCreateMessage)))
       (field (header /:message-header))
       (field (channel-number /client-channel-number)
	      ;; TODO: is it already controlled, or will it be controlled?
	      (synopsis "ID of a channel controlled by this client"))
       (field (peer /peer-identity)
	      ;; TODO: local peer, remote peer?
	      (synopsis "Channel's peer"))
       (field (port /hashcode:512)
	      (synopsis "Port of this channel"))
       (field (options u32/big)))) ;; TODO: which ones?

    (define-type /:msg:cadet:local:channel:destroy
      (structure/packed
       ;; TODO: 'for' or 'from'?
       (synopsis "Message for or to a client to destroy a tunnel.")
       (properties '((message-symbol . msg:cadet:local:channel:destroy)
		     (c-type . GNUNET_CADET_LocalChannelDestroyMessage)))
       (field (header /:message-header))
       (field (channel-number /client-channel-number))))

    (define-type /:msg:cadet:local:data
      (structure/packed
       (synopsis "Header for CADET data traffic, followed by actual data")
       (properties '((c-type . GNUNET_CADET_LocalData)
		     (message-symbol msg:cadet:local:data)))
       (field (header /:message-header))
       (field (channel-number /client-channel-number)
	      (synopsis "ID of the channel"))
       ;; TODO GNUNET_MQ_PriorityPreferences
       (field (priority-preference u32/big)
	      (synopsis "priority and preferences"))))

    (define-type /:msg:cadet:local:acknowledgement
      (structure/packed
       (synopsis "Message sent from the service to the client, to inform the
client that more data can be sent across a channel.")
       (properties '((c-type . GNUNET_CADET_LocalAck)
		     (message-symbol . msg:cadet:local:acknowledgement)))
       (field (header /:message-header))
       (field (client-channel-number /client-channel-number)
	      (synopsis "ID of the channel allowed to send more data"))))))
